<template>
  <div class="gantt-chart">
    <!-- 甘特图工具栏 -->
    <div class="gantt-toolbar">
      <div class="toolbar-left">
        <el-button size="small" @click="zoomIn" :disabled="zoomLevel >= 3">
          <el-icon><ZoomIn /></el-icon>
          放大
        </el-button>
        <el-button size="small" @click="zoomOut" :disabled="zoomLevel <= 0">
          <el-icon><ZoomOut /></el-icon>
          缩小
        </el-button>
        <el-button size="small" @click="fitToScreen">
          <el-icon><FullScreen /></el-icon>
          适应屏幕
        </el-button>
        <el-button size="small" @click="toggleToday">
          <el-icon><Calendar /></el-icon>
          {{ showToday ? '隐藏今日' : '显示今日' }}
        </el-button>
      </div>
      <div class="toolbar-right">
        <el-select v-model="viewMode" size="small" style="width: 120px;">
          <el-option label="周视图" value="week" />
          <el-option label="月视图" value="month" />
          <el-option label="季度视图" value="quarter" />
        </el-select>
      </div>
    </div>

    <!-- 甘特图主体 -->
    <div class="gantt-body" ref="ganttContainer">
      <!-- 左侧任务列表 -->
      <div class="gantt-sidebar" :style="{ width: sidebarWidth + 'px' }">
        <div class="sidebar-header">
          <div class="header-cell task-name">任务名称</div>
          <div class="header-cell task-weight">权重</div>
          <div class="header-cell task-progress">进度</div>
        </div>
        <div class="sidebar-content">
          <div 
            v-for="task in ganttData" 
            :key="task.id"
            class="task-row"
            :class="{ 'task-row-hover': hoveredTask === task.id }"
            @mouseenter="hoveredTask = task.id"
            @mouseleave="hoveredTask = null"
          >
            <div class="task-cell task-name">
              <div class="task-info">
                <div class="task-code">{{ task.phase_code }}</div>
                <div class="task-desc">{{ task.phase_desc }}</div>
              </div>
            </div>
            <div class="task-cell task-weight">
              <el-tag size="small" type="primary">{{ task.weight }}%</el-tag>
            </div>
            <div class="task-cell task-progress">
              <el-progress 
                :percentage="getTaskProgress(task)" 
                :status="getProgressStatus(task)"
                :stroke-width="6"
                size="small"
              />
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧时间轴和进度条 -->
      <div class="gantt-timeline" ref="timelineContainer">
        <!-- 时间轴头部 -->
        <div class="timeline-header" :style="{ height: headerHeight + 'px' }">
          <div 
            v-for="(date, index) in visibleDates" 
            :key="date"
            class="timeline-header-cell"
            :style="{ width: cellWidth + 'px' }"
          >
            <div class="date-label">{{ formatTimelineDate(date) }}</div>
            <div class="date-sub-label">{{ getDateSubLabel(date) }}</div>
          </div>
        </div>

        <!-- 时间轴内容 -->
        <div class="timeline-content" :style="{ height: contentHeight + 'px' }">
          <div 
            v-for="task in ganttData" 
            :key="task.id"
            class="timeline-row"
            :style="{ height: rowHeight + 'px' }"
          >
            <div 
              v-for="(date, index) in visibleDates" 
              :key="date"
              class="timeline-cell"
              :style="{ width: cellWidth + 'px' }"
            >
              <!-- 进度条 -->
              <div 
                v-if="hasProgress(task, date)"
                class="progress-bar"
                :class="getProgressBarClass(task, date)"
                :style="getProgressBarStyle(task, date)"
                @click="handleProgressClick(task, date)"
                @mouseenter="hoveredProgress = { task: task.id, date }"
                @mouseleave="hoveredProgress = null"
              >
                <div class="progress-tooltip" v-if="hoveredProgress && hoveredProgress.task === task.id && hoveredProgress.date === date">
                  {{ getProgressTooltip(task, date) }}
                </div>
              </div>
              
              <!-- 今日标记 -->
              <div 
                v-if="showToday && isToday(date)"
                class="today-marker"
              ></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 图例 -->
    <div class="gantt-legend">
      <div class="legend-item">
        <div class="legend-color completed"></div>
        <span>已完成</span>
      </div>
      <div class="legend-item">
        <div class="legend-color in-progress"></div>
        <span>进行中</span>
      </div>
      <div class="legend-item">
        <div class="legend-color pending"></div>
        <span>待开始</span>
      </div>
      <div class="legend-item">
        <div class="legend-color delayed"></div>
        <span>已延期</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { ZoomIn, ZoomOut, FullScreen, Calendar } from '@element-plus/icons-vue'

// Props
const props = defineProps({
  data: {
    type: Array,
    default: () => []
  },
  timePeriods: {
    type: Array,
    default: () => []
  },
  height: {
    type: Number,
    default: 400
  }
})

// Emits
const emit = defineEmits(['progress-click', 'task-click'])

// 响应式数据
const zoomLevel = ref(1)
const viewMode = ref('week')
const showToday = ref(true)
const hoveredTask = ref(null)
const hoveredProgress = ref(null)
const ganttContainer = ref(null)
const timelineContainer = ref(null)

// 计算属性
const ganttData = computed(() => {
  return props.data.map(task => ({
    ...task,
    progress: typeof task.progress === 'string' ? JSON.parse(task.progress) : task.progress
  }))
})

const visibleDates = computed(() => {
  const dates = props.timePeriods
  const startIndex = Math.max(0, Math.floor(scrollOffset.value / cellWidth.value))
  const endIndex = Math.min(dates.length, startIndex + visibleCells.value)
  return dates.slice(startIndex, endIndex)
})

const sidebarWidth = computed(() => 280)
const headerHeight = computed(() => 60)
const rowHeight = computed(() => 40)
const contentHeight = computed(() => ganttData.value.length * rowHeight.value)
const cellWidth = computed(() => 80 + (zoomLevel.value - 1) * 20)
const visibleCells = computed(() => {
  if (!timelineContainer.value) return 10
  return Math.floor(timelineContainer.value.clientWidth / cellWidth.value)
})

const scrollOffset = ref(0)

// 方法
function zoomIn() {
  if (zoomLevel.value < 3) {
    zoomLevel.value++
    ElMessage.success('已放大')
  }
}

function zoomOut() {
  if (zoomLevel.value > 0) {
    zoomLevel.value--
    ElMessage.success('已缩小')
  }
}

function fitToScreen() {
  zoomLevel.value = 1
  scrollOffset.value = 0
  ElMessage.success('已适应屏幕')
}

function toggleToday() {
  showToday.value = !showToday.value
}

function formatTimelineDate(dateStr) {
  if (!dateStr || dateStr.length !== 8) return '-'
  const year = dateStr.substring(0, 4)
  const month = dateStr.substring(4, 6)
  const day = dateStr.substring(6, 8)
  return `${month}/${day}`
}

function getDateSubLabel(dateStr) {
  if (!dateStr || dateStr.length !== 8) return ''
  const date = new Date(
    parseInt(dateStr.substring(0, 4)),
    parseInt(dateStr.substring(4, 6)) - 1,
    parseInt(dateStr.substring(6, 8))
  )
  const today = new Date()
  const diffTime = date.getTime() - today.getTime()
  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
  
  if (diffDays === 0) return '今日'
  if (diffDays > 0) return `+${diffDays}天`
  return `${diffDays}天`
}

function getTaskProgress(task) {
  // 计算任务的总进度（所有时间周期的平均完成率）
  const progressData = task.progress || {}
  const completionRates = Object.values(progressData).map(p => parseInt(p.completion_rate) || 0)
  if (completionRates.length === 0) return 0
  
  const totalProgress = completionRates.reduce((sum, rate) => sum + rate, 0)
  return Math.round(totalProgress / completionRates.length)
}

function getProgressStatus(task) {
  const progress = getTaskProgress(task)
  if (progress >= 100) return 'success'
  if (progress >= 80) return 'warning'
  if (progress > 0) return ''
  return 'exception'
}

function hasProgress(task, date) {
  const progressData = task.progress || {}
  const dateProgress = progressData[date]
  return dateProgress && parseInt(dateProgress.completion_rate) > 0
}

function getProgressBarClass(task, date) {
  const progressData = task.progress || {}
  const dateProgress = progressData[date]
  const completionRate = parseInt(dateProgress?.completion_rate) || 0
  
  if (completionRate >= 100) return 'completed'
  if (completionRate >= 50) return 'in-progress'
  if (completionRate > 0) return 'started'
  return 'pending'
}

function getProgressBarStyle(task, date) {
  const progressData = task.progress || {}
  const dateProgress = progressData[date]
  const completionRate = parseInt(dateProgress?.completion_rate) || 0
  
  return {
    width: `${completionRate}%`,
    height: '20px',
    borderRadius: '4px',
    transition: 'all 0.3s ease'
  }
}

function getProgressTooltip(task, date) {
  const progressData = task.progress || {}
  const dateProgress = progressData[date]
  const completionRate = parseInt(dateProgress?.completion_rate) || 0
  const completedWeight = parseFloat(dateProgress?.completed_weight) || 0
  
  return `${task.phase_code}: ${completionRate}% (权重: ${completedWeight})`
}

function isToday(dateStr) {
  if (!dateStr || dateStr.length !== 8) return false
  const date = new Date(
    parseInt(dateStr.substring(0, 4)),
    parseInt(dateStr.substring(4, 6)) - 1,
    parseInt(dateStr.substring(6, 8))
  )
  const today = new Date()
  return date.toDateString() === today.toDateString()
}

function handleProgressClick(task, date) {
  emit('progress-click', { task, date })
}

// 监听器
watch(() => props.data, () => {
  nextTick(() => {
    // 数据变化时重新计算布局
  })
}, { deep: true })

// 生命周期
onMounted(() => {
  // 初始化甘特图
  console.log('甘特图组件已挂载')
})
</script>

<style scoped>
.gantt-chart {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
}

.gantt-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
}

.toolbar-left {
  display: flex;
  gap: 8px;
}

.toolbar-right {
  display: flex;
  gap: 8px;
}

.gantt-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.gantt-sidebar {
  background: #f8f9fa;
  border-right: 1px solid #e9ecef;
  overflow: hidden;
}

.sidebar-header {
  display: flex;
  background: #e9ecef;
  border-bottom: 1px solid #dee2e6;
  font-weight: 600;
  font-size: 12px;
  color: #495057;
}

.header-cell {
  padding: 8px 12px;
  border-right: 1px solid #dee2e6;
}

.header-cell:last-child {
  border-right: none;
}

.task-name {
  flex: 2;
}

.task-weight {
  flex: 1;
  text-align: center;
}

.task-progress {
  flex: 1;
  text-align: center;
}

.sidebar-content {
  overflow-y: auto;
}

.task-row {
  display: flex;
  border-bottom: 1px solid #f1f3f4;
  transition: background-color 0.2s ease;
}

.task-row:hover {
  background-color: #f8f9fa;
}

.task-row-hover {
  background-color: #e3f2fd;
}

.task-cell {
  padding: 8px 12px;
  border-right: 1px solid #f1f3f4;
  display: flex;
  align-items: center;
}

.task-cell:last-child {
  border-right: none;
}

.task-info {
  flex: 1;
}

.task-code {
  font-weight: 600;
  font-size: 12px;
  color: #303133;
  margin-bottom: 2px;
}

.task-desc {
  font-size: 11px;
  color: #606266;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gantt-timeline {
  flex: 1;
  overflow: hidden;
  position: relative;
}

.timeline-header {
  display: flex;
  background: #e9ecef;
  border-bottom: 1px solid #dee2e6;
  position: sticky;
  top: 0;
  z-index: 10;
}

.timeline-header-cell {
  border-right: 1px solid #dee2e6;
  padding: 8px 4px;
  text-align: center;
  font-size: 11px;
  color: #495057;
  position: relative;
}

.timeline-header-cell:last-child {
  border-right: none;
}

.date-label {
  font-weight: 600;
  margin-bottom: 2px;
}

.date-sub-label {
  font-size: 10px;
  color: #6c757d;
}

.timeline-content {
  overflow: auto;
  position: relative;
}

.timeline-row {
  display: flex;
  border-bottom: 1px solid #f1f3f4;
}

.timeline-cell {
  border-right: 1px solid #f1f3f4;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.timeline-cell:last-child {
  border-right: none;
}

.progress-bar {
  position: relative;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.progress-bar:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.progress-bar.completed {
  background: linear-gradient(90deg, #67c23a, #85ce61);
}

.progress-bar.in-progress {
  background: linear-gradient(90deg, #409eff, #66b1ff);
}

.progress-bar.started {
  background: linear-gradient(90deg, #e6a23c, #ebb563);
}

.progress-bar.pending {
  background: linear-gradient(90deg, #f56c6c, #f78989);
}

.progress-tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #303133;
  color: #fff;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 11px;
  white-space: nowrap;
  z-index: 1000;
  margin-bottom: 4px;
}

.progress-tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: #303133;
}

.today-marker {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  background: #f56c6c;
  z-index: 5;
}

.gantt-legend {
  display: flex;
  gap: 16px;
  padding: 12px 16px;
  background: #f8f9fa;
  border-top: 1px solid #e9ecef;
  justify-content: center;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #606266;
}

.legend-color {
  width: 16px;
  height: 8px;
  border-radius: 2px;
}

.legend-color.completed {
  background: linear-gradient(90deg, #67c23a, #85ce61);
}

.legend-color.in-progress {
  background: linear-gradient(90deg, #409eff, #66b1ff);
}

.legend-color.pending {
  background: linear-gradient(90deg, #e6a23c, #ebb563);
}

.legend-color.delayed {
  background: linear-gradient(90deg, #f56c6c, #f78989);
}

/* 滚动条样式 */
.sidebar-content::-webkit-scrollbar,
.timeline-content::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.sidebar-content::-webkit-scrollbar-track,
.timeline-content::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.sidebar-content::-webkit-scrollbar-thumb,
.timeline-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.sidebar-content::-webkit-scrollbar-thumb:hover,
.timeline-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style> 